package com.cskaoyan.market.controller.admin;

import com.cskaoyan.market.db.domain.MarketAdmin;
import com.cskaoyan.market.db.domain.MarketRole;
import com.cskaoyan.market.db.domain.MarketUser;
import com.cskaoyan.market.db.mapper.MarketAdminMapper;
import com.cskaoyan.market.db.mapper.MarketPermissionMapper;
import com.cskaoyan.market.db.mapper.MarketRoleMapper;
import com.cskaoyan.market.service.AdminRoleService;
import com.cskaoyan.market.shiro.MarketToken;
import com.cskaoyan.market.util.AdminResponseCode;
import com.cskaoyan.market.util.Permission;
import com.cskaoyan.market.util.PermissionUtil;
import com.cskaoyan.market.util.ResponseUtil;
import com.cskaoyan.market.vo.PermVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServlet;
import java.util.*;

@RestController
@RequestMapping("/admin/auth")
public class AdminAuthController extends HttpServlet {



    private static final String YOUR_PACKAGE_NAME = "com.cskaoyan.market.controller.admin";


    private List<PermVo> systemPermissions;

    private Set<String> systemPermissionsString = null;


    @Autowired
    private SecurityManager securityManager;
    @Autowired
    MarketAdminMapper marketAdminMapper;
    @Autowired
    MarketRoleMapper marketRoleMapper;
    @Autowired
    MarketPermissionMapper marketPermissionMapper;
    @Autowired
    AdminRoleService service ;
    @Autowired
    private ApplicationContext context;



    @GetMapping("info")
    @RequiresAuthentication
    public Object info() {
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();

        MarketAdmin admin = (MarketAdmin) session.getAttribute("user");
        Map<String, Object> data = new HashMap<>();
        //查roles
        MarketAdmin marketAdmin = marketAdminMapper.selectByPrimaryKey(admin.getId());
        Integer[] roleIds = marketAdmin.getRoleIds();
        String[] roles = new String[roleIds.length];
        for (int i = 0; i < roleIds.length; i++) {
            MarketRole marketRole = marketRoleMapper.selectByPrimaryKey(roleIds[i]);
            roles[i]=marketRole.getName();
        }
        //查perms
        systemPermissions = getSystemPermissions();
        Set<String> assignedPermissions = new HashSet<>();
        for (PermVo permVo : systemPermissions) {
            recursive(permVo, assignedPermissions);
        }
        String[] perms = new String[assignedPermissions.size()];
        int i = 0;
        for (String assignedPermission : assignedPermissions) {
            perms[i] = assignedPermission;
            i++;
        }
        Boolean ifSuper = false;
        for (Integer roleId : roleIds) {
            if (roleId == 1) ifSuper = true;
        }
        List<String> permsTemp = new ArrayList<>();
        if(!ifSuper)
        {
            Set<String> assignedPermissions1Temp = new HashSet<>();
            for (Integer roleId : roleIds) {
                Set<String> assignedPermissions1 = getAssignedPermissions(roleId);
                for (String s : assignedPermissions1) {
                    assignedPermissions1Temp.add(s)
;                }
            }
            for (String s : assignedPermissions1Temp) {
                String s1 =s.replaceAll(":", "/");
                for (int i1 = 0; i1 < perms.length; i1++) {
                    if (perms[i1].split(" ")[1].contains(s1))
                        permsTemp.add(perms[i1]);
                }
            }
        }
        else permsTemp.add("*");
        data.put("roles", roles);
        data.put("name", admin.getUsername());
        data.put("perms", permsTemp);
        data.put("avatar", admin.getAvatar());
            return ResponseUtil.ok(data);
    }

    private void recursive(PermVo permVo, Set<String> assignedPermissions) {
        List<PermVo> children = permVo.getChildren();
        if(children != null){
            //next level
            for (PermVo child : children) {
                recursive(child, assignedPermissions);
            }
        }else {
            assignedPermissions.add(permVo.getApi());
        }
    }

    private List<PermVo> getSystemPermissions() {
        String basicPackage = YOUR_PACKAGE_NAME;
        if (systemPermissions == null) {
            List<Permission> permissions = PermissionUtil.listPermission(context, basicPackage);
            systemPermissions = PermissionUtil.listPermVo(permissions);
            systemPermissionsString = PermissionUtil.listPermissionString(permissions);
        }
        return systemPermissions;
    }
    private Set<String> getAssignedPermissions(Integer roleId) {

        Set<String>  assignedPermissions = service.selectPermission(roleId);
        return assignedPermissions;

    }

    @PostMapping("logout")
    public Object logout(){
        return ResponseUtil.ok(null);
    }

    @PostMapping("login")
    public Object login(@RequestBody Map map){
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
            return ResponseUtil.badArgument();
        }

        MarketToken token = new MarketToken(username, password,"admin");
        try {
            subject.login(token);
        }catch (Exception e){
            return ResponseUtil.fail(AdminResponseCode.USER_INVALID_PASSWORD, "用户名或者密码错误");
        }
        MarketAdmin user = (MarketAdmin)subject.getPrincipal();
        Session session = subject.getSession();
        session.setAttribute("user", user);
        Map<String, String> userInfo = new HashMap<>();
        userInfo.put("nickName", user.getUsername());
        userInfo.put("avatarUrl", user.getAvatar());
        Map<String, Object> data = new HashMap<>();
        data.put("userInfo", userInfo);
        data.put("token", session.getId());
        Object ok = ResponseUtil.ok(data);
        return ok;
    }
}
